#coding:utf-8
'''获取验证码'''

from . import api
from ihome.utils.captcha.captcha import captcha
from flask import request,jsonify, current_app
from ihome.utils.response_code import RET,error_map
from ihome import redis_store

from ihome import constants
from ihome.libs.yuntongxun import sms

import re
import random



# 命名规则 域名:api/版本/资源 根据不同请求来获取资源信息  get查,post增加,put修改,delete删除
@api.route('/verify_code')
def get_verify_code():
    """get方式获得验证码图片"""
    '''
    1.获取参数
    2.检验参数
    3.业务逻辑处理
    4.返回值
    '''

    # 获取传过来的code_id,为什么请求的时候需要带这个参数?
    # 因为唯一性,还有发现前端写js时,如果不改变src中的url,那么就不能切换图片
    code_id= request.args.get('code_id')
    # 如果不存在,则直接返回参数错误
    if not code_id:
        return jsonify(errono=RET.PARAMERR,errmsg=error_map.get(RET.PARAMERR))
    # 3.业务逻辑处理,用utils里面的captcha包生成验证码
    name, code_text, code_img = captcha.generate_captcha()


    #将code_id与code_text存在redis中
    #构造这样的键值对,键名:verify_code_%s % code_id   值:code_text
    key = 'verify_code_%s' % code_id
    #todo 存储也会出错
    try:
        redis_store.set(key, code_text, ex=constants.REDIS_EXPIRE_TIME)
    except Exception as e:
        # 将错误信息存储在log中
        current_app.logger.error(e)
        return jsonify(errono=RET.DATAERR, errmsg=error_map.get(RET.DATAERR))
    else:
        # 这步可以直接返回img图片
        return code_img


# 短信验证码获取,这个就不用上面那种方式了.
# url:127.0.0.1:5000/api/v1.0/sms_code/mobile
@api.route('/sms_code/<re("1[3578]\d{9}"):mobile>',methods=['GET'])
def get_sms_code(mobile):
    """获取短信验证码 get请求
        获取参数  手机号与图片验证码,code_id
        检验参数  都必须存在,手机号验证11位,图片验证码验证
        业务逻辑  生成手机验证码,调用发送短信模板,
        返回数据  返回json数据,成功..

        细节处理:
        手机号是否请求过
        图片验证码不能重复使用
        短信sms_text保存
        60s不能重复请求

    """
    code_id = request.args.get('code_id')
    code_text = request.args.get('code_text')

    if not all([code_id,code_text]):
        return jsonify(errono=RET.PARAMERR, errmsg="请求参数不完全")


    # 验证图片验证码
    key = 'verify_code_%s' % code_id
    try:
        real_code_text = redis_store.get(key)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errono=RET.DATAERR, errmsg="获取验证码错误")

    # 验证码是否过期
    if not real_code_text:
        return jsonify(errono=RET.PARAMERR, errmsg="验证码失效")
    else:
        # 清除该验证码
        try:
            redis_store.delete(key)
        except Exception as e:
            current_app.logger.error(e)
        # 验证码错误
        if real_code_text.upper() != code_text.upper():
            return jsonify(errono=RET.PARAMERR, errmsg="验证码出错")

    # 60s不能重复提交
    try:
        redis_mobile = redis_store.get(mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errono=RET.DATAERR, errmsg="获取数据失败")
    if redis_mobile:
        return jsonify(errono=RET.REQERR, errmsg="非法请求或请求次数受限")
    # 60s内不能重复请求,设置手机验证
    redis_store.set(mobile,1, ex=constants.MOBILE_DURATION)



    # 发送短信-1 生成短信验证码,并存入redis
    sms_text = "%06d" % random.randint(10000,999999)
    # 保存sms_text
    key = 'sms_text_'+mobile
    try:
        redis_store.set(key,sms_text,ex=constants.MOBILE_TEXT_DURATION)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errono=RET.DATAERR, errmsg="数据存入错误")

    # 发送短信-2 调用sms发送短信模块发送
    try:
        sms_obj = sms.SendSMS()
        result = sms_obj.send_sms(mobile, {sms_text,int(constants.MOBILE_TEXT_DURATION/60)}, 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errono=RET.THIRDERR, errmsg='第三方短信发送失败')

    # 发送短信-3 返回发送成功或者失败信息
    if result == 0:
        return jsonify(errono=RET.OK, errmsg='发送成功')
    else:
        return jsonify(errono=RET.THIRDERR, errmsg='第三方短信发送失败')





